home *** CD-ROM | disk | FTP | other *** search
- /* Handling of assorted minor windows for the Mac interface to Xconq.
- Copyright (C) 1992, 1993, 1994, 1995 Stanley T. Shebs.
-
- Xconq is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version. See the file COPYING. */
-
- #include "conq.h"
- #include "macconq.h"
- extern int do_key_down_construction(int);
-
- /* Globals for the game window. */
-
- WindowPtr gamewin = nil;
-
- int gamewinw = 200;
- int gamedatehgt = 18;
- int gameclockoffset;
- int gameclockhgt = 15;
- int gamenoteoffset;
- int gamenotehgt = 15;
- int gametophgt;
-
- int gamesidehgt = 24;
- int gamesideclockhgt = 15;
- int gamesideclockoffset;
- int gamesidescorehgt = 15;
- int gamesidescoreoffset;
-
- Handle aisicnhandle = nil;
- Handle facesicnhandle[3];
-
- char *game_progress_str = "";
-
- time_t lastnow;
-
- /* Globals for the construction window. */
-
- WindowPtr constructionwin = nil;
-
- ListHandle construction_unit_list = nil;
- ListHandle constructiontypelist = nil;
-
- int constructmargin = 5;
- int constructtop = 32;
-
- /* This is the vector of units that can do construction or research. */
-
- UnitVector *possibleunits = NULL;
-
- int numposstypes;
- int *possibletypes = NULL;
-
- int currunlength = 99;
-
- ControlHandle constructbutton;
- ControlHandle researchbutton;
-
- TEHandle run_length_text = nil;
-
- Rect runlengthrect, unitlistrect, typelistrect;
-
- /* Globals for unit closeup windows. */
-
- int lastunitcloseuph = -1, lastunitcloseupv = -1;
-
- /* Globals for the history window. */
-
- WindowPtr historywin = nil;
-
- HistEvent **histcontents = NULL;
-
- int numhistcontents = 0;
-
- ControlHandle histvscrollbar;
-
- int history_line_spacing = 15; /* (should derive from font) */
-
- int history_top_line_height = 25;
-
- HistEvent *firstvisevt = NULL;
-
- HistEvent *secondvisevt = NULL;
-
- int numvishistlines;
-
- int total_history_lines = 0;
-
- /* The game progress window. */
-
- /* Create the game progress window. */
-
- void
- create_game_window()
- {
- extern int numscores;
-
- /* Create the window, color if possible, since emblems may be in color. */
- if (hasColorQD) {
- gamewin = GetNewCWindow(wGame, NULL, (WindowPtr) -1L);
- } else {
- gamewin = GetNewWindow(wGame, NULL, (WindowPtr) -1L);
- }
- gametophgt = gamedatehgt;
- if (g_rt_per_turn() > 0 || g_rt_for_game() > 0) {
- gameclockoffset = gametophgt;
- gametophgt += gameclockhgt;
- }
- gamenoteoffset = gametophgt;
- gametophgt += gamenotehgt;
- /* Add some space if sides have a per-turn and/or per-game clock. */
- if (g_rt_per_side() > 0) {
- gamesideclockoffset = gamesidehgt;
- gamesidehgt += gamesideclockhgt;
- }
- /* Add additional space for each two scorekeepers. */
- if (keeping_score()) {
- gamesidescoreoffset = gamesidehgt;
- gamesidehgt += gamesidescorehgt * ((numscorekeepers + 1) / 2);
- }
- /* This is not growable, so we have to ensure it's big enough to start with. */
- SizeWindow(gamewin, gamewinw, gametophgt + numsides * gamesidehgt, 1);
- if (first_windows) {
- GDHandle main_screen = GetMainDevice();
- int main_screen_width, main_screen_height;
- Rect gdrect = (*main_screen)->gdRect;
-
- main_screen_width = gdrect.right - gdrect.left;
- main_screen_height = gdrect.bottom - gdrect.top;
- MoveWindow(gamewin,
- main_screen_width - gamewinw - 3,
- 40,
- FALSE);
- }
- /* Get handles to useful sicns. */
- aisicnhandle = GetNamedResource('SICN', "\pmplayer");
- facesicnhandle[0] = GetNamedResource('SICN', "\phostile");
- facesicnhandle[1] = GetNamedResource('SICN', "\pneutral");
- facesicnhandle[2] = GetNamedResource('SICN', "\pfriendly");
- }
-
- void
- draw_game()
- {
- Side *side2;
- GrafPtr oldport;
-
- if (gamewin == nil)
- return;
- GetPort(&oldport);
- SetPort(gamewin);
- draw_game_date();
- draw_game_progress();
- /* Draw a solid separating line between date info and side list. */
- MoveTo(0, gametophgt);
- Line(gamewinw, 0);
- for_all_sides(side2)
- draw_game_side(side2);
- SetPort(oldport);
- }
-
- /* Display the current time and date and any realtime countdowns. */
-
- void
- draw_game_date()
- {
- Rect tmprect;
-
- SetRect(&tmprect, 0, 0, gamewinw, gamedatehgt - 1);
- EraseRect(&tmprect);
- MoveTo(tmprect.left + 10, tmprect.top + 12);
- TextFace(bold);
- DrawString((unsigned char *) curdatestr);
- TextFace(0);
- /* (should draw season name here somewhere?) */
- draw_game_clocks();
- if (endofgame) {
- gray_out_rect(&tmprect);
- }
- #ifdef DEBUGGING
- /* Indicate the state of all the debug flags. */
- if (Debug || DebugM || DebugG) {
- sprintf(spbuf, "%c%c%c",
- (Debug ? 'D' : ' '), (DebugM ? 'M' : ' '), (DebugG ? 'G' : ' '));
- MoveTo(tmprect.right - 30, tmprect.top + 12);
- DrawText(spbuf, 0, strlen(spbuf));
- }
- #endif /* DEBUGGING */
- }
-
- void
- draw_game_clocks()
- {
- int elapsed, s2, sy;
- time_t now;
- Rect tmprect;
- Side *side2;
-
- /* Draw per-turn and per-game time limits that for the game as a whole. */
- SetRect(&tmprect, 0, gamedatehgt, gamewinw / 2, gamedatehgt + gameclockhgt - 1);
- if (g_rt_per_turn() > 0) {
- time(&now);
- elapsed = (int) difftime(now, turn_play_start_in_real_time);
- time_desc(spbuf, g_rt_per_turn() - elapsed, g_rt_per_turn());
- EraseRect(&tmprect);
- MoveTo(tmprect.left + 20, tmprect.top + 10);
- DrawText(spbuf, 0, strlen(spbuf));
- lastnow = now;
- }
- OffsetRect(&tmprect, 100, 0);
- if (g_rt_for_game() > 0) {
- time(&now);
- elapsed = (int) difftime(now, game_start_in_real_time);
- time_desc(spbuf, g_rt_for_game() - elapsed, g_rt_for_game());
- EraseRect(&tmprect);
- MoveTo(tmprect.left + 10, tmprect.top + 10);
- DrawText(spbuf, 0, strlen(spbuf));
- lastnow = now;
- }
- /* Draw per-side clocks if any limits defined. */
- if (g_rt_per_side() > 0) {
- for_all_sides(side2) {
- if (side2->ingame) {
- s2 = side_number(side2);
- sy = gametophgt + (s2 - 1) * gamesidehgt + gamesideclockoffset;
- elapsed = 0;
- if (!side2->finishedturn)
- elapsed = (int) difftime(now, turn_play_start_in_real_time); /* should be side start */
- time_desc(spbuf, g_rt_per_side() - side2->totaltimeused - elapsed, g_rt_per_side());
- SetRect(&tmprect, 0, sy, gamewinw, sy + gamesideclockhgt - 1);
- EraseRect(&tmprect);
- MoveTo(tmprect.left + 20, tmprect.top + 10);
- DrawText(spbuf, 0, strlen(spbuf));
- /* (should draw per-turn side usage) */
- }
- }
- }
- }
-
- void
- draw_game_progress()
- {
- Rect tmprect;
-
- SetRect(&tmprect, 0, gamenoteoffset, gamewinw, gamenoteoffset + gamenotehgt - 1);
- EraseRect(&tmprect);
- MoveTo(1, gamenoteoffset + 12);
- DrawText(game_progress_str, 0, strlen(game_progress_str));
- }
-
- /* Draw info about a given side. */
-
- void
- draw_game_side(Side *side2)
- {
- int s2 = side_number(side2);
- int sx = 20, sy = gametophgt + (s2 - 1) * gamesidehgt;
-
- draw_side_emblem(gamewin, 2, sy + 4, 16, 16, s2, shadow_emblem);
- strcpy(spbuf, short_side_title(side2));
- MoveTo(sx, sy + 12);
- /* Put the name of our side in boldface. */
- TextFace((side2 == dside ? bold : 0));
- DrawText(spbuf, 0, strlen(spbuf));
- TextFace(0);
- if (side_has_ai(side2) && side2->ingame) {
- /* Show that the side is run by an AI. */
- plot_sicn(gamewin, 182, sy + 2, aisicnhandle, 0, TRUE, srcOr);
- }
- if (side2 != dside
- && side2->ingame
- && (side_has_ai(side2) || side_has_display(side2))) {
- /* Indicate attitude of other side. */
- plot_sicn(gamewin, 164, sy + 2,
- facesicnhandle[feeling_towards(side2, dside)], 0, TRUE, srcOr);
- }
- draw_side_status(side2);
- /* Draw a separating line. */
- PenPat(QDPat(gray));
- MoveTo(0, sy + gamesidehgt);
- Line(gamewinw, 0);
- PenNormal();
- }
-
- /* (should make this more generic) */
-
- int
- feeling_towards(Side *side, Side *side2)
- {
- if (trusted_side(side2, side)) {
- return 2;
- } else if (side_has_ai(side) && should_try_to_win(side)) {
- return 0;
- } else {
- return 1;
- }
- }
-
- /* Draw the current details about a side. */
-
- void
- draw_side_status(Side *side2)
- {
- int sx, sy = gametophgt + (side_number(side2) - 1) * gamesidehgt, i;
- int totacp, resvacp, acpleft, percentleft, percentresv;
- Rect siderect, tmprect, progressrect;
- Scorekeeper *sk;
- extern int curpriority;
-
- SetRect(&siderect, 0, sy + 1, gamewinw, sy + gamesidehgt);
- if (!side2->ingame || endofgame) {
- gray_out_rect(&siderect);
- if (side_won(side2)) {
- /* (should) Indicate that this side has won. */
- /* draw like a trophy or flourishes or some such?) */
- } else if (side_lost(side2)) {
- /* Draw a (solid) line crossing out the loser. Simple and obvious. */
- MoveTo(1, sy + 8);
- Line(gamewin->portRect.right - 3, 0);
- }
- } else {
- /* Set up and clear the area where we show progress. */
- SetRect(&progressrect, 20, sy + 12 + 4, 20 + 100, sy + 12 + 4 + 7);
- EraseRect(&progressrect);
- if (!g_use_side_priority() || curpriority == side2->priority) {
- /* Show the current acp totals/progress of the side. */
- /* This is not quite the security hole it might seem,
- you don't get much advantage out of seeing how far along each side is,
- and it gives you a feel for how the turn is progressing. */
- totacp = side_initacp(side2);
- if (totacp > 0) {
- FrameRect(&progressrect);
- acpleft = side_acp(side2);
- resvacp = side_acp_reserved(side2);
- if (totacp > 0) {
- percentleft = (100 * acpleft) / totacp;
- percentleft = max(0, min(99, percentleft));
- percentresv = (100 * resvacp) / totacp;
- percentresv = max(0, min(99, percentresv));
- } else {
- percentleft = percentresv = 0;
- }
- if (percentleft > 0) {
- tmprect = progressrect;
- InsetRect(&tmprect, 1, 1);
- tmprect.right = tmprect.left + percentleft;
- FillRect(&tmprect, QDPat(black));
- }
- if (percentresv > 0) {
- PenPat(QDPat(gray));
- MoveTo(progressrect.left + 1 + percentresv, progressrect.top);
- Line(0, 6);
- PenNormal();
- /* (or could draw a grayish area??) */
- }
- } else {
- /* Draw a gray frame to indicate that this side has no units
- that can actually do anything. */
- PenPat(QDPat(gray));
- FrameRect(&progressrect);
- PenNormal();
- }
- }
- /* (should this be a generic kernel test?) */
- if (side2->finishedturn || !(side_has_ai(side2) || side_has_display(side2))) {
- tmprect = progressrect;
- InsetRect(&tmprect, 1, 1);
- gray_out_rect(&tmprect);
- }
- }
- if (keeping_score()) {
- siderect.top += gamesidescoreoffset;
- siderect.bottom = siderect.top + gamesidescorehgt - 1;
- i = 0;
- for_all_scorekeepers(sk) {
- if (symbolp(sk->body)
- && match_keyword(sk->body, K_LAST_SIDE_WINS)) {
- int points = 0;
- Unit *unit;
-
- for_all_side_units(side2, unit) {
- if (in_play(unit) && completed(unit)) {
- points += unit_point_value(unit);
- }
- }
- sprintf(spbuf, "Point Value: %d", points);
- } else {
- /* Compose the generic scorekeeper status display. */
- if (sk->title != NULL) {
- sprintf(spbuf, "%s", sk->title);
- } else {
- sprintf(spbuf, "SK #%d", sk->id);
- }
- if (sk->scorenum >= 0) {
- tprintf(spbuf, ": %d", side2->scores[sk->scorenum]);
- }
- }
- if ((i & 1) == 0)
- EraseRect(&siderect);
- sx = (((i & 1) == 1) ? gamewinw / 2 : 0);
- /* Draw the scorekeeper's status. */
- MoveTo(sx + 10, siderect.top + 10);
- DrawText(spbuf, 0, strlen(spbuf));
- ++i;
- if ((i & 1) == 0)
- OffsetRect(&siderect, 0, gamesidescorehgt);
- }
- }
- }
-
- void
- do_mouse_down_game(Point mouse, int mods)
- {
- beep();
- }
-
- /* The construction planning window. */
-
- void
- create_construction_window()
- {
- int done = FALSE;
- Point cellsize;
- Rect listrect, tmprect;
-
- if (hasColorQD) {
- constructionwin = GetNewCWindow(wConstruction, NULL, (WindowPtr) -1L);
- } else {
- constructionwin = GetNewWindow(wConstruction, NULL, (WindowPtr) -1L);
- }
- constructbutton = GetNewControl(cConstructButton, constructionwin);
- researchbutton = GetNewControl(cResearchButton, constructionwin);
- SetPort(constructionwin);
- calc_construction_rects();
- run_length_text = TENew(&runlengthrect, &runlengthrect);
- TESetSelect(0, 32767, run_length_text);
- TEDelete(run_length_text);
- /* (should seed with a heuristic "reasonable" value) */
- sprintf(tmpbuf, "%d", currunlength);
- TEInsert(tmpbuf, strlen(tmpbuf), run_length_text);
- /* Switch to a font for the lists. */
- TextFont(monaco);
- TextSize(9);
- /* Set up the list of all constructing units. */
- tmprect = unitlistrect;
- tmprect.right -= sbarwid;
- SetRect(&listrect, 0, 0, 1, 0);
- SetPt(&cellsize, 300, 12);
- /* Create the list of units itself. */
- construction_unit_list =
- LNew(&tmprect, &listrect, cellsize, 128, constructionwin,
- FALSE, FALSE, FALSE, TRUE);
- /* Now set up the list of types. */
- tmprect = typelistrect;
- tmprect.right -= sbarwid;
- SetRect(&listrect, 0, 0, 1, 0);
- /* (should calc this from the desired font) */
- SetPt(&cellsize, 300, 12);
- constructiontypelist =
- LNew(&tmprect, &listrect, cellsize, 128, constructionwin,
- FALSE, FALSE, FALSE, TRUE);
- init_construction_lists();
- if (1) {
- GDHandle main_screen = GetMainDevice();
- int main_screen_width, main_screen_height;
- Rect tmprect = constructionwin->portRect;
- Rect gdrect = (*main_screen)->gdRect;
-
- main_screen_width = gdrect.right - gdrect.left;
- main_screen_height = gdrect.bottom - gdrect.top;
- MoveWindow(constructionwin,
- 4,
- main_screen_height - (tmprect.bottom - tmprect.top) - 3,
- FALSE);
- }
- ShowWindow(constructionwin);
- }
-
- void
- init_construction_lists()
- {
- int u;
- Unit *unit;
- Cell tmpcell;
-
- /* Update the list of units. */
- LDoDraw(0, construction_unit_list);
- LDelRow(0, 0, construction_unit_list);
- SetPt(&tmpcell, 0, 0);
- /* Create the vector of constructing units, at a reasonable initial size. */
- if (possibleunits == NULL) {
- possibleunits = make_unit_vector(max(50, numunits));
- }
- clear_unit_vector(possibleunits);
- for_all_side_units(dside, unit) {
- maybe_add_unit_to_construction_list(unit);
- }
- LDoDraw(1, construction_unit_list);
- /* Update the list of types. */
- LDoDraw(0, constructiontypelist);
- LDelRow(0, 0, constructiontypelist);
- SetPt(&tmpcell, 0, 0);
- if (possibletypes == NULL)
- possibletypes = (int *) xmalloc(numutypes * sizeof(int));
- numposstypes = 0;
- for_all_unit_types(u) {
- if (1 /* could be built by some unit that could be on the side */) {
- LAddRow(1, tmpcell.v, constructiontypelist);
- constructible_desc(spbuf, dside, u, NULL);
- LSetCell(spbuf, strlen(spbuf), tmpcell, constructiontypelist);
- ++tmpcell.v;
- possibletypes[numposstypes++] = u;
- }
- }
- LDoDraw(1, constructiontypelist);
- adjust_construction_controls();
- }
-
- void
- reinit_construction_lists()
- {
- init_construction_lists();
- }
-
- /* Draw the construction window by updating the lists and framing them. */
-
- void
- draw_construction()
- {
- Rect tmprect;
-
- calc_construction_rects();
- TEUpdate(&(constructionwin->portRect), run_length_text);
- tmprect = runlengthrect;
- InsetRect(&tmprect, -1, -1);
- FrameRect(&tmprect);
- LUpdate(constructionwin->visRgn, construction_unit_list);
- tmprect = unitlistrect;
- InsetRect(&tmprect, -1, -1);
- FrameRect(&tmprect);
- #if 0
- for_all_unit_types(u) {
- if (1 /* could be built by some unit that could be on the side */) {
- constructible_desc(spbuf, dside, u, possibleunits);
- SetPt(&tmpcell, 0, u);
- LSetCell(spbuf, strlen(spbuf), tmpcell, constructiontypelist);
- }
- }
- #endif
- LUpdate(constructionwin->visRgn, constructiontypelist);
- tmprect = typelistrect;
- InsetRect(&tmprect, -1, -1);
- FrameRect(&tmprect);
- /* Maybe show the construct button as the default. */
- draw_construction_default();
- }
-
- /* Draw a heavy outline around the construction button. */
-
- void
- draw_construction_default()
- {
- Rect tmprect;
- GrafPtr oldport;
-
- GetPort(&oldport);
- SetPort(constructionwin);
- tmprect = (*constructbutton)->contrlRect;
- PenSize(3, 3);
- InsetRect(&tmprect, -4, -4);
- if ((*constructbutton)->contrlHilite != 0) {
- PenMode(patBic);
- }
- FrameRoundRect(&tmprect, 16, 16);
- PenNormal();
- SetPort(oldport);
- }
-
- /* Figure out how to subdivide the construction window for the two lists. */
-
- void
- calc_construction_rects()
- {
- int wid, hgt, divide;
- Rect tmprect;
-
- tmprect = constructionwin->portRect;
- runlengthrect = tmprect;
- runlengthrect.left = runlengthrect.right - 100; runlengthrect.top = 5;
- runlengthrect.right -= 20; runlengthrect.bottom = 25;
- wid = tmprect.right - tmprect.left - sbarwid;
- hgt = tmprect.bottom - tmprect.top - sbarwid;
- if (wid / 2 > 220 /* maxtypewid */) {
- divide = wid - 220;
- } else {
- divide = wid / 2;
- }
- SetRect(&unitlistrect, 0, constructtop, divide, hgt);
- InsetRect(&unitlistrect, constructmargin, constructmargin);
- SetRect(&typelistrect, divide, constructtop, wid, hgt);
- InsetRect(&typelistrect, constructmargin, constructmargin);
- }
-
- void
- activate_construction(int activate)
- {
- if (activate)
- TEActivate(run_length_text);
- else
- TEDeactivate(run_length_text);
- LActivate(activate, construction_unit_list);
- LActivate(activate, constructiontypelist);
- }
-
- Unit *
- get_selected_construction_unit()
- {
- Point tmpcell;
- Unit *unit;
-
- SetPt(&tmpcell, 0, 0);
- if (LGetSelect(TRUE, &tmpcell, construction_unit_list)) {
- if (tmpcell.v < possibleunits->numunits) {
- unit = (possibleunits->units)[tmpcell.v].unit;
- if (is_acting(unit))
- return unit;
- }
- }
- return NULL;
- }
-
- int
- get_selected_construction_type()
- {
- Point tmpcell;
-
- SetPt(&tmpcell, 0, 0);
- if (LGetSelect(TRUE, &tmpcell, constructiontypelist)) {
- if (tmpcell.v < numposstypes) {
- return possibletypes[tmpcell.v];
- }
- }
- return NONUTYPE;
- }
-
- void
- scroll_to_selected_construction_unit()
- {
- Unit *unit;
-
- /* Beep and return if there are no maps open currently. */
- if (maplist == NULL) {
- beep();
- return;
- }
- unit = get_selected_construction_unit();
- if (unit != NULL && inside_area(unit->x, unit->y))
- scroll_best_map_to_unit(unit);
- }
-
- /* Handle a click anywhere within the construction window. */
-
- void
- do_mouse_down_construction(Point mouse, int mods)
- {
- ControlHandle control;
- short part;
- int u;
- Unit *unit;
- extern int modal_construction;
- extern WindowPtr window_behind_construction;
-
- part = FindControl(mouse, constructionwin, &control);
- if (control == constructbutton) {
- if ((unit = get_selected_construction_unit()) != NULL) {
- if ((u = get_selected_construction_type()) != NONUTYPE) {
- push_build_task(unit, u, currunlength);
- execute_task(unit);
- update_construction_unit_list(unit);
- if (modal_construction && window_behind_construction != nil)
- SelectWindow(window_behind_construction);
- window_behind_construction = NULL;
- modal_construction = FALSE;
- return;
- }
- }
- } else if (control == researchbutton) {
- if ((unit = get_selected_construction_unit()) != NULL) {
- if ((u = get_selected_construction_type()) != NONUTYPE) {
- push_research_task(unit, u, u_tech_to_build(u));
- execute_task(unit);
- update_construction_unit_list(unit);
- if (modal_construction && window_behind_construction != nil)
- SelectWindow(window_behind_construction);
- window_behind_construction = NULL;
- modal_construction = FALSE;
- return;
- }
- }
- } else if (PtInRect(mouse, &runlengthrect)) {
- TEClick(mouse, mods, run_length_text);
- /* (what else to do?) */
- } else if (PtInRect(mouse, &unitlistrect)) {
- LClick(mouse, mods, construction_unit_list);
- /* Update the type list to show what could be built and in how long. */
- update_type_list_for_unit(get_selected_construction_unit());
- } else if (PtInRect(mouse, &typelistrect)) {
- LClick(mouse, mods, constructiontypelist);
- /* Update the unit list to show what could build the type */
- update_unit_list_for_type(get_selected_construction_type());
- } else {
- /* Click was not in any useful part of the window. */
- }
- }
-
- int
- do_key_down_construction(key)
- int key;
- {
- int len;
- char buffer[10];
- CharsHandle text;
-
- if (1 /* textedit active */) {
- TEKey(key, run_length_text);
- text = TEGetText(run_length_text);
- len = max((*run_length_text)->teLength, 9);
- strncpy(buffer, *text, len);
- buffer[len] = '\0';
- currunlength = atoi(buffer);
- return TRUE;
- }
- return FALSE;
- }
-
- /* Highlight exactly one specific unit in the construction window, and unhighlight
- any others. */
-
- void
- select_unit_in_construction_window(Unit *unit)
- {
- int i;
- Point tmpcell;
-
- for (i = 0; i < possibleunits->numunits; ++i) {
- SetPt(&tmpcell, 0, i);
- LSetSelect((unit == (possibleunits->units)[i].unit), tmpcell, construction_unit_list);
- LAutoScroll(construction_unit_list);
- }
- update_type_list_for_unit(get_selected_construction_unit());
- }
-
- void
- select_type_in_construction_window(int u)
- {
- int i;
- Point tmpcell;
-
- for (i = 0; i < numutypes; ++i) {
- SetPt(&tmpcell, 0, i);
- LSetSelect((u == i), tmpcell, constructiontypelist);
- LAutoScroll(constructiontypelist);
- }
- if (u == NONUTYPE)
- return;
- update_unit_list_for_type(get_selected_construction_type());
- }
-
- /* Given a unit (which may be any unit), update the list of constructing units. */
-
- void
- update_construction_unit_list(Unit *unit)
- {
- int i, u;
- Point tmpcell;
-
- if (constructionwin == nil)
- return;
- u = get_selected_construction_type();
- /* We need to look for it even if it might not be ours, since it might
- have been captured or otherwise lost, and needs to be removed. */
- for (i = 0; i < possibleunits->numunits; ++i) {
- if (unit == (possibleunits->units)[i].unit) {
- SetPt(&tmpcell, 0, i);
- if (is_active(unit)
- && can_build(unit)
- && side_controls_unit(dside, unit)) {
- construction_desc(spbuf, unit, u);
- LSetCell(spbuf, strlen(spbuf), tmpcell, construction_unit_list);
- } else {
- remove_unit_from_vector(possibleunits, unit, i);
- LDelRow(1, tmpcell.v, construction_unit_list);
- }
- return;
- }
- }
- /* Unit was not found, try to add it to the list. */
- maybe_add_unit_to_construction_list(unit);
- }
-
- void
- maybe_add_unit_to_construction_list(Unit *unit)
- {
- Point tmpcell;
-
- if (is_acting(unit)
- && can_build(unit)
- && side_controls_unit(dside, unit)) {
- /* Add this unit to the vector of constructing units. */
- possibleunits = add_unit_to_vector(possibleunits, unit, 0);
- /* (should sort and maybe rearrange list here) */
- /* Add a row at the end of the list. */
- SetPt(&tmpcell, 0, possibleunits->numunits - 1);
- LAddRow(1, possibleunits->numunits - 1, construction_unit_list);
- construction_desc(spbuf, unit, get_selected_construction_type());
- LSetCell(spbuf, strlen(spbuf), tmpcell, construction_unit_list);
- }
- }
-
- void
- update_unit_list_for_type(int u)
- {
- int i;
- Point tmpcell;
- Unit *unit;
-
- for (i = 0; i < possibleunits->numunits; ++i) {
- unit = (possibleunits->units)[i].unit;
- if (unit != NULL) {
- SetPt(&tmpcell, 0, i);
- if (is_acting(unit) && unit->side == dside) {
- construction_desc(spbuf, unit, u);
- LSetCell(spbuf, strlen(spbuf), tmpcell, construction_unit_list);
- } else {
- /* LDelRow(1, tmpcell.v, construction_unit_list); */
- LSetCell("", 0, tmpcell, construction_unit_list);
- }
- }
- }
- adjust_construction_controls();
- }
-
- void
- update_construction_type_list()
- {
- int u;
-
- if (constructionwin == nil)
- return;
- u = get_selected_construction_type();
- update_type_list_for_unit(get_selected_construction_unit());
- }
-
- void
- update_type_list_for_unit(Unit *unit)
- {
- int u;
- Point tmpcell;
-
- for_all_unit_types(u) {
- if (1 /* could be built by some unit that could be on the side */) {
- SetPt(&tmpcell, 0, u);
- constructible_desc(spbuf, dside, u, get_selected_construction_unit());
- LSetCell(spbuf, strlen(spbuf), tmpcell, constructiontypelist);
- }
- }
- adjust_construction_controls();
- }
-
- /* Enable/disable controls according to whether the selected list elements can
- do construction activities. */
-
- void
- adjust_construction_controls()
- {
- int u, canconstruct = FALSE, canresearch = FALSE;
- Unit *unit;
-
- unit = get_selected_construction_unit();
- if (unit != NULL) {
- u = get_selected_construction_type();
- if (u != NONUTYPE) {
- if (uu_acp_to_create(unit->type, u) > 0)
- canconstruct = TRUE;
- if (uu_acp_to_research(unit->type, u) > 0)
- canresearch = TRUE;
- }
- }
- HiliteControl(constructbutton, (canconstruct ? 0 : 255));
- HiliteControl(researchbutton, (canresearch ? 0 : 255));
- draw_construction_default();
- }
-
- /* Resize the construction window to the given size. */
-
- static void adjust_construction_items(void);
-
- void
- grow_construction(int h, int v)
- {
- EraseRect(&constructionwin->portRect);
- SizeWindow(constructionwin, h, v, 1);
- adjust_construction_items();
- /* This will force a full redraw at the next update. */
- InvalRect(&constructionwin->portRect);
- }
-
- /* Zooming "rightsizes" the window. */
-
- void
- zoom_construction(int part)
- {
- int titleh, vislinesavail;
- Rect zoomrect;
- GDHandle zoomgd;
-
- EraseRect(&constructionwin->portRect);
- if (part == inZoomOut) {
- if (!hasColorQD) {
- /* If no Color QD, then there is only one screen. */
- zoomrect = QD(screenBits).bounds;
- } else {
- zoomgd = best_zoom_screen(&constructionwin->portRect);
- zoomrect = (*zoomgd)->gdRect;
- if (zoomgd == GetMainDevice()) {
- zoomrect.top += GetMBarHeight();
- }
- titleh = 20; /* (should calc) */
- zoomrect.top += titleh;
- }
- InsetRect(&zoomrect, 4, 4);
- /* If not many units or types, shrink the zoomed window to fit. */
- vislinesavail = (zoomrect.bottom - zoomrect.top - sbarwid) / 15;
- if (0 /*vislinesavail > total_history_lines*/) {
- zoomrect.bottom = zoomrect.top + 20 /*total_history_lines*/ * 15 + sbarwid;
- }
- (*((WStateDataHandle) ((WindowPeek) constructionwin)->dataHandle))->stdState = zoomrect;
- }
- ZoomWindow(constructionwin, part, (constructionwin == FrontWindow()));
- adjust_construction_items();
- /* This will force a full redraw at the next update. */
- InvalRect(&constructionwin->portRect);
- }
-
- /* Move and resize the list and text objects in the construction window. */
-
- static void
- adjust_construction_items()
- {
- /* Recalculate size and position. */
- calc_construction_rects();
- /* Resize the run length text item. */
- (*run_length_text)->viewRect = runlengthrect;
- (*run_length_text)->destRect = runlengthrect;
- TECalText(run_length_text);
- /* Resize the unit list. */
- LSize(unitlistrect.right - unitlistrect.left - sbarwid,
- unitlistrect.bottom - unitlistrect.top,
- construction_unit_list);
- /* Move the type list (is this the approved way to do it?) */
- (*constructiontypelist)->rView.left = typelistrect.left;
- LSize(typelistrect.right - typelistrect.left - sbarwid,
- typelistrect.bottom - typelistrect.top,
- constructiontypelist);
- }
-
- /* The side renaming dialog includes places for all the different name-related
- properties of a side. */
-
- void
- side_rename_dialog(Side *side)
- {
- short done = FALSE, changed = TRUE, ditem;
- Str255 tmpstr;
- DialogPtr win;
- short itemtype; Handle itemhandle; Rect itemrect;
-
- win = GetNewDialog(dSideRename, NULL, (DialogPtr) -1L);
- while (!done) {
- if (changed) {
- /* Seed the items with the current side names. */
- GetDItem(win, diSideRenameName, &itemtype, &itemhandle, &itemrect);
- c2p((side->name ? side->name : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameFullName, &itemtype, &itemhandle, &itemrect);
- c2p((side->longname ? side->longname : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameAcronym, &itemtype, &itemhandle, &itemrect);
- c2p((side->shortname ? side->shortname : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameNoun, &itemtype, &itemhandle, &itemrect);
- c2p((side->noun ? side->noun : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenamePluralNoun, &itemtype, &itemhandle, &itemrect);
- c2p((side->pluralnoun ? side->pluralnoun : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameAdjective, &itemtype, &itemhandle, &itemrect);
- c2p((side->adjective ? side->adjective : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameEmblemName, &itemtype, &itemhandle, &itemrect);
- c2p((side->emblemname ? side->emblemname : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- GetDItem(win, diSideRenameColorScheme, &itemtype, &itemhandle, &itemrect);
- c2p((side->colorscheme ? side->colorscheme : ""), tmpstr);
- SetIText(itemhandle, tmpstr);
- ShowWindow(win);
- changed = FALSE;
- }
- draw_default_button(win, diSideRenameOK);
- SetCursor(&QD(arrow));
- ModalDialog(NULL, &ditem);
- switch (ditem) {
- case diSideRenameOK:
- /* Actually change the side's slots. */
- GetDItem(win, diSideRenameName, &itemtype, &itemhandle, &itemrect);
- set_side_name(dside, dside, get_string_from_item(itemhandle));
- GetDItem(win, diSideRenameFullName, &itemtype, &itemhandle, &itemrect);
- side->longname = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenameAcronym, &itemtype, &itemhandle, &itemrect);
- side->shortname = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenameNoun, &itemtype, &itemhandle, &itemrect);
- side->noun = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenamePluralNoun, &itemtype, &itemhandle, &itemrect);
- side->pluralnoun = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenameAdjective, &itemtype, &itemhandle, &itemrect);
- side->adjective = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenameEmblemName, &itemtype, &itemhandle, &itemrect);
- side->emblemname = get_string_from_item(itemhandle);
- GetDItem(win, diSideRenameColorScheme, &itemtype, &itemhandle, &itemrect);
- side->colorscheme = get_string_from_item(itemhandle);
- /* Tweak the side menu. */
- update_side_menu(dside);
- /* Force redisplay of everything that might use any side names. */
- force_overall_update();
- /* Fall into next case. */
- case diSideRenameCancel:
- done = TRUE;
- break;
- case diSideRenameRandom:
- side->name = NULL;
- side->noun = NULL;
- /* always need to clear this cache before renaming... */
- side->pluralnoun = NULL;
- side->adjective = NULL;
- make_up_side_name(side);
- init_emblem_images(side);
- changed = TRUE;
- break;
- }
- }
- DisposDialog(win);
- }
-
- /* Unit naming/renaming. */
-
- int
- unit_rename_dialog(Unit *unit)
- {
- short done = FALSE, ditem;
- char *newname;
- char *namer = unit_namer(unit);
- Str255 tmpstr;
- DialogPtr win;
- short itemtype; Handle itemhandle; Rect itemrect;
-
- if (unit == NULL)
- return FALSE;
- win = GetNewDialog(dRename, NULL, (DialogPtr) -1L);
- /* Seed the text item with the original name. */
- newname = unit->name;
- if (newname == NULL)
- newname = "";
- GetDItem(win, diRenameName, &itemtype, &itemhandle, &itemrect);
- c2p(newname, tmpstr);
- SetIText(itemhandle, tmpstr);
- /* Gray out the random renaming button if no namers available. */
- GetDItem(win, diRenameRandom, &itemtype, &itemhandle, &itemrect);
- HiliteControl((ControlHandle) itemhandle, ((namer != NULL) ? 0 : 255));
- ShowWindow(win);
- while (!done) {
- draw_default_button(win, diRenameOK);
- SetCursor(&QD(arrow));
- ModalDialog(NULL, &ditem);
- switch (ditem) {
- case diRenameOK:
- GetDItem(win, diRenameName, &itemtype, &itemhandle, &itemrect);
- set_unit_name(dside, unit, get_string_from_item(itemhandle));
- /* Fall into next case. */
- case diRenameCancel:
- done = TRUE;
- break;
- case diRenameRandom:
- newname = propose_unit_name(unit);
- GetDItem(win, diRenameName, &itemtype, &itemhandle, &itemrect);
- c2p(newname, tmpstr);
- SetIText(itemhandle, tmpstr);
- break;
- }
- }
- DisposDialog(win);
- return TRUE;
- }
-
- /* Unit closeups. */
-
- UnitCloseup *
- find_unit_closeup(Unit *unit)
- {
- UnitCloseup *unitcloseup;
-
- for_all_unit_closeups(unitcloseup) {
- if (unitcloseup->unit == unit
- && unitcloseup->window
- && ((WindowPeek) unitcloseup->window)->visible)
- return unitcloseup;
- }
- return NULL;
- }
-
- void
- create_unit_closeup(Unit *unit)
- {
- int u, w, h;
- WindowPtr win;
- UnitCloseup *unitcloseup = (UnitCloseup *) xmalloc(sizeof(UnitCloseup));
-
- if (!active_display(dside) || unit == NULL) return;
- DGprintf("Creating a closeup of %s\n", unit_desig(unit));
- u = unit->type;
- unitcloseup->unit = unit;
- if (hasColorQD) {
- win = GetNewCWindow(wUnitCloseup, nil, (WindowPtr) -1L);
- } else {
- win = GetNewWindow(wUnitCloseup, nil, (WindowPtr) -1L);
- }
- unitcloseup->window = win;
- stagger_window(unitcloseup->window, &lastunitcloseuph, &lastunitcloseupv);
- preferred_closeup_size(u, &w, &h);
- SizeWindow(win, w, h, 1);
- /* (should use unit's name if it has one!) */
- sprintf(spbuf, "%s #%d Closeup", u_type_name(u), unit->id);
- add_window_menu_item(spbuf, win);
- unitcloseup->next = unitcloseuplist;
- unitcloseuplist = unitcloseup;
- /* We're now ready to show this closeup to the world. */
- ShowWindow(win);
- }
-
- static char *nummrows;
-
- int closeupspacing = 16;
-
- int closeupwinwid = 200;
-
- void
- preferred_closeup_size(int u, int *widp, int *hgtp)
- {
- int wid = closeupwinwid, hgt, m, u2, count;
-
- hgt = 4 + 32 + 4 + 3 * closeupspacing;
- if (nummrows == NULL) {
- nummrows = xmalloc(numutypes);
- for_all_unit_types(u2) {
- nummrows[u2] = count = 0;
- for_all_material_types(m) {
- if (um_storage_x(u2, m) > 0)
- ++count;
- }
- if (count > 0) {
- nummrows[u2] = max(1, count / 2);
- }
- }
- }
- hgt += nummrows[u] * closeupspacing;
- if (u_acp(u) > 0) hgt += 5 * closeupspacing;
- /* (should make some room for tooling state) */
- *widp = wid; *hgtp = hgt;
- }
-
- /* Draw all the fields and displays in a unit closeup. */
-
- void
- draw_unit_closeup(UnitCloseup *unitcloseup)
- {
- int u, m, sx = 4, sy, count, sx2, sy2;
- char tmpbuf[BUFSIZE];
- Rect tmprect;
- GrafPtr oldport;
- WindowPtr win = unitcloseup->window;
- Unit *unit = unitcloseup->unit;
-
- if (!active_display(dside)) return;
- if (!in_play(unit) || !(side_controls_unit(dside, unit) || endofgame)) {
- /* If the unit is no longer alive and ours, shut down the window. */
- remove_window_menu_item(win);
- destroy_unit_closeup(unitcloseup);
- HideWindow(win);
- return;
- }
- GetPort(&oldport);
- SetPort(win);
- EraseRect(&win->portRect);
- u = unit->type;
- /* Draw the unit's image. */
- SetRect(&tmprect, sx, sx, sx + 32, sx + 32);
- EraseRect(&tmprect);
- draw_unit_image(win, tmprect.left, tmprect.top,
- tmprect.right - tmprect.left, tmprect.bottom - tmprect.top,
- u, side_number(unit->side), !completed(unit));
- /* Draw the unit's name. */
- name_or_number(unit, tmpbuf);
- MoveTo(44, 4 + closeupspacing);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- if (Debug || DebugG || DebugM) {
- sprintf(tmpbuf, " %d ", unit->id);
- MoveTo(closeupwinwid - 30, 15);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- }
- /* Draw the unit's side and type. */
- side_and_type_name(tmpbuf, dside, u, unit->side);
- MoveTo(44, 4 + closeupspacing * 2);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- /* Draw the unit's location. */
- if (unit->z != 0) {
- sprintf(tmpbuf, "; alt %d", unit->z);
- } else {
- strcpy(tmpbuf, "");
- }
- sprintf(spbuf, "at %d,%d%s", unit->x, unit->y, tmpbuf);
- if (unit->transport != NULL) {
- sprintf(tmpbuf, "In %s (%s)", short_unit_handle(unit->transport), spbuf);
- } else {
- strcpy(tmpbuf, spbuf);
- }
- sy = 4 + 32 + 4 + closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- /* Draw the unit's hit points. */
- hp_desc(tmpbuf, unit, TRUE);
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- /* Draw the unit's current ACP, if applicable. */
- if (u_acp(u) > 0) {
- acp_desc(tmpbuf, unit, TRUE);
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- }
- /* Draw the unit's supplies. */
- count = 0;
- if (nummrows[u] > 0)
- sy += closeupspacing;
- for_all_material_types(m) {
- if (um_storage_x(u, m) > 0) {
- strcpy(tmpbuf, m_type_name(m));
- sx2 = sx + (count >= nummrows[u] ? closeupwinwid/2 : 0); sy2 = sy + (count % nummrows[u]) * closeupspacing;
- MoveTo(sx2, sy2);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- sprintf(tmpbuf, "%d/%d", unit->supply[m], um_storage_x(u, m));
- MoveTo(sx2 + (closeupwinwid/2 - 4 - 4 - TextWidth(tmpbuf, 0, strlen(tmpbuf))), sy2);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- ++count;
- }
- }
- if (nummrows[u] > 0)
- sy += (nummrows[u] - 1) * closeupspacing;
- /* Draw the unit's plan, if it has one. */
- if (unit->plan) {
- Task *task;
- extern char *plantypenames[];
- Plan *plan = unit->plan;
-
- sprintf(tmpbuf, "Plan: %s", plantypenames[plan->type]);
- if (plan->waitingfortasks) strcat(tmpbuf, " [wait]");
- if (plan->delayed) strcat(tmpbuf, " [delay]");
- if (plan->reserve) strcat(tmpbuf, " [resv]");
- if (plan->asleep) strcat(tmpbuf, " [aslp]");
- if (plan->aicontrol) strcat(tmpbuf, " [dlgt]");
- if (plan->supply_is_low) strcat(tmpbuf, " [low]");
- if (plan->supply_alarm) strcat(tmpbuf, " [alrm]");
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- if (plan->maingoal) {
- /* (should use a "goal_desc" routine) */
- strcpy(tmpbuf, goal_desig(plan->maingoal));
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- }
- if (plan->formation) {
- /* (should use a "goal_desc" routine) */
- strcpy(tmpbuf, goal_desig(plan->formation));
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- }
- if (plan->tasks) {
- for (task = plan->tasks; task != NULL; task = task->next) {
- task_desc(tmpbuf, task);
- sy += closeupspacing;
- MoveTo(sx, sy);
- DrawText(tmpbuf, 0, strlen(tmpbuf));
- }
- }
- }
- SetPort(oldport);
- }
-
-
- UnitCloseup *
- unit_closeup_from_window(WindowPtr win)
- {
- UnitCloseup *unitcloseup;
-
- for_all_unit_closeups(unitcloseup) {
- if (unitcloseup->window == win) return unitcloseup;
- }
- return NULL;
- }
-
- int
- do_mouse_down_unit_closeup(UnitCloseup *unitcloseup, Point mouse, int mods)
- {
- ControlHandle control;
- short part;
- WindowPtr window = unitcloseup->window;
-
- part = FindControl(mouse, window, &control);
- if (0 /* some control */) {
- } else {
- /* This just forces a redraw of the window - kind of crude. */
- update_unit_display(dside, unitcloseup->unit, TRUE);
- return TRUE;
- }
- }
-
- void
- destroy_unit_closeup(UnitCloseup *unitcloseup)
- {
- UnitCloseup *unitcloseup2;
-
- if (unitcloseuplist == unitcloseup) {
- unitcloseuplist = unitcloseup->next;
- } else {
- for_all_unit_closeups(unitcloseup2) {
- if (unitcloseup2->next == unitcloseup) {
- unitcloseup2->next = unitcloseup->next;
- }
- }
- }
- /* (should destroy substructs) */
- free(unitcloseup);
- }
-
- /* History window. */
-
- int maxvishistlines = 200;
-
- void
- create_history_window()
- {
- Rect vscrollrect;
-
- historywin = GetNewWindow(wHistory, NULL, (WindowPtr) -1L);
- /* (should calc max based on size of font and height of screen) */
- histcontents = (HistEvent **) xmalloc(maxvishistlines * sizeof(HistEvent *));
- vscrollrect = historywin->portRect;
- vscrollrect.top -= 1;
- vscrollrect.bottom -= sbarwid - 1;
- vscrollrect.left = vscrollrect.right - sbarwid;
- vscrollrect.right += 1;
- histvscrollbar = NewControl(historywin, &vscrollrect, "\p", TRUE,
- 0, 0, 100, scrollBarProc, 0L);
- firstvisevt = history->next;
- secondvisevt = firstvisevt->next;
- update_total_hist_lines();
- set_history_scrollbar();
- }
-
- void
- calc_history_layout()
- {
- update_total_hist_lines();
- set_history_scrollbar();
- }
-
- void
- update_total_hist_lines()
- {
- HistEvent *hevt;
-
- total_history_lines = 0;
- for (hevt = history->next; hevt != history; hevt = hevt->next) {
- if (side_in_set(dside, hevt->observers)) {
- if (hevt->startdate != hevt->prev->startdate) ++total_history_lines;
- ++total_history_lines;
- }
- }
- }
-
- void
- set_history_scrollbar()
- {
- int hgt, oldmax;
- HistEvent *nexthevt;
-
- hgt = historywin->portRect.bottom - historywin->portRect.top;
- numvishistlines = (hgt - history_line_spacing - sbarwid) / history_line_spacing;
- oldmax = GetCtlMax(histvscrollbar);
- SetCtlMax(histvscrollbar, max(0, total_history_lines - numvishistlines + 1));
- HiliteControl(histvscrollbar, (numvishistlines < total_history_lines ? 0 : 255));
- /* If the thumb was at max, move it to the new max. */
- if (GetCtlValue(histvscrollbar) == oldmax) {
- SetCtlValue(histvscrollbar, GetCtlMax(histvscrollbar));
- if (GetCtlValue(histvscrollbar) == 0) {
- firstvisevt = history->next;
- secondvisevt = firstvisevt->next;
- } else {
- firstvisevt = get_nth_history_line(dside, GetCtlValue(histvscrollbar), &nexthevt);
- secondvisevt = nexthevt;
- }
- }
- }
-
- void
- draw_history()
- {
- int i, headdate;
- HistEvent *hevt;
- int numchars;
- char *datestr, hdatebuf[100];
-
- if (!active_display(dside) || historywin == nil) return;
- /* Build up the array of events and dates to draw. */
- numhistcontents = 0;
- hevt = firstvisevt;
- if (hevt == NULL) {
- histcontents[numhistcontents++] = NULL;
- hevt = secondvisevt;
- }
- for (; hevt != history; hevt = hevt->next) {
- if (numhistcontents >= numvishistlines) break;
- if (side_in_set(dside, hevt->observers)) {
- if (numhistcontents > 0
- && histcontents[numhistcontents - 1] != NULL
- && hevt->startdate != histcontents[numhistcontents - 1]->startdate) {
- histcontents[numhistcontents++] = NULL;
- }
- histcontents[numhistcontents++] = hevt;
- }
- }
- /* Draw the header line. */
- MoveTo(2, 10);
- headdate = (firstvisevt ? firstvisevt : secondvisevt)->startdate;
- /* (should be relative) */
- datestr = absolute_date_string(headdate);
- sprintf(hdatebuf, "(%s)", datestr);
- /* (should clip to drawing only visible chars) */
- numchars = strlen(hdatebuf);
- DrawText(hdatebuf, 0, numchars);
- /* Now draw each event or date. */
- for (i = 0; i < numhistcontents; ++i) {
- if (histcontents[i] != NULL) {
- draw_historical_event(histcontents[i], i);
- } else {
- draw_historical_date(histcontents[i+1], i);
- }
- }
- }
-
- void
- draw_historical_event(HistEvent *hevt, int y)
- {
- int numchars;
- char hevtbuf[500];
-
- if (hevt == NULL) return;
- MoveTo(20, history_line_spacing * y + history_top_line_height);
- historical_event_desc(dside, hevt, hevtbuf);
- /* (should clip to drawing only visible chars) */
- numchars = strlen(hevtbuf);
- DrawText(hevtbuf, 0, numchars);
- }
-
- void
- draw_historical_date(HistEvent *hevt, int y)
- {
- int numchars;
- char *datestr, hdatebuf[100];
-
- if (hevt == NULL) return;
- MoveTo(2, history_line_spacing * y + history_top_line_height);
- /* (should be relative) */
- datestr = absolute_date_string(hevt->startdate);
- strcpy(hdatebuf, datestr);
- /* (should clip to drawing only visible chars) */
- numchars = strlen(hdatebuf);
- DrawText(hdatebuf, 0, numchars);
- }
-
- void
- update_history_window(HistEvent *hevt)
- {
- HistEvent *prevfirst, *prevsecond;
-
- prevfirst = firstvisevt;
- prevsecond = secondvisevt;
- SetPort(historywin);
- calc_history_layout();
- if (firstvisevt != prevfirst
- || secondvisevt != prevsecond
- || numvishistlines > total_history_lines) {
- force_update(historywin);
- }
- }
-
- pascal void
- history_scroll_proc(ControlHandle control, short code)
- {
- int curvalue, maxvalue, pagesize, jump;
-
- curvalue = GetCtlValue(control);
- maxvalue = GetCtlMax(control);
- pagesize = numvishistlines;
- switch (code) {
- case inPageDown:
- jump = max(1, pagesize - 2);
- break;
- case inDownButton:
- jump = 1;
- break;
- case inPageUp:
- jump = min(-1, - (pagesize - 2));
- break;
- case inUpButton:
- jump = -1;
- break;
- default:
- jump = 0;
- break;
- }
- curvalue = max(min(curvalue + jump, maxvalue), 0);
- SetCtlValue(control, curvalue);
- }
-
- void
- do_mouse_down_history(Point mouse, int mods)
- {
- HistEvent *prevfirst, *prevsecond, *nexthevt;
- ControlHandle control;
- short part, value;
-
- part = FindControl(mouse, historywin, &control);
- if (control == histvscrollbar) {
- prevfirst = firstvisevt;
- prevsecond = secondvisevt;
- switch (part) {
- case inThumb:
- part = TrackControl(control, mouse, NULL);
- break;
- default:
- part = TrackControl(control, mouse, (ProcPtr) history_scroll_proc);
- break;
- }
- value = GetCtlValue(control);
- firstvisevt = get_nth_history_line(dside, value, &nexthevt);
- secondvisevt = nexthevt;
- if (firstvisevt != prevfirst || secondvisevt != prevsecond) {
- force_update(historywin);
- }
- } else {
- /* anything to do here? */
- }
- }
-
- /* Grow/shrink the history window to the given size. */
-
- void
- grow_history(int h, int v)
- {
- EraseRect(&historywin->portRect);
- SizeWindow(historywin, h, v, 1);
- move_history_scrollbar(h, v);
- /* This will force a full redraw at the next update. */
- InvalRect(&historywin->portRect);
- }
-
- /* Zoom the history window to its best maximal size. */
-
- void
- zoom_history(int part)
- {
- int titleh, vislinesavail;
- Rect zoomrect;
- GDHandle zoomgd;
-
- EraseRect(&historywin->portRect);
- if (part == inZoomOut) {
- if (!hasColorQD) {
- /* If no Color QD, then there is only one screen. */
- zoomrect = QD(screenBits).bounds;
- } else {
- zoomgd = best_zoom_screen(&historywin->portRect);
- zoomrect = (*zoomgd)->gdRect;
- if (zoomgd == GetMainDevice()) {
- zoomrect.top += GetMBarHeight();
- }
- titleh = 20; /* (should calc) */
- zoomrect.top += titleh;
- }
- InsetRect(&zoomrect, 4, 4);
- /* If not much history, shrink the zoomed window to fit. */
- vislinesavail = (zoomrect.bottom - zoomrect.top - sbarwid) / history_line_spacing;
- update_total_hist_lines();
- if (vislinesavail > total_history_lines) {
- zoomrect.bottom = zoomrect.top + total_history_lines * history_line_spacing + sbarwid;
- }
- (*((WStateDataHandle) ((WindowPeek) historywin)->dataHandle))->stdState = zoomrect;
- }
- ZoomWindow(historywin, part, (historywin == FrontWindow()));
- move_history_scrollbar(window_width(historywin), window_height(historywin));
- /* This will force a full redraw at the next update. */
- InvalRect(&historywin->portRect);
- }
-
- void
- move_history_scrollbar(int h, int v)
- {
- MoveControl(histvscrollbar, h - sbarwid, 0);
- SizeControl(histvscrollbar, sbarwid + 1, v - sbarwid + 1);
- set_history_scrollbar();
- }
-